using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Rogue
{
    // this class stores per-entity-subclass images for bodyparts in the detail window.
    public class DetailWindowImages
    {
        // compute the bbox for mouse clicks. Ideally, we'd test against alpha or something...
        struct TexAndBBox
        {
            public Texture2D m_Texture;
            public Rectangle m_BBox;
        }

        Dictionary<string, TexAndBBox> m_PartsToImages;
        
        string m_TypeName;
        public string TypeName
            { get { return m_TypeName; } }

        // calculate the bounding box of the non-alpha'd-out pixels in an image,
        // so the user can click in the part's bounding box to select an enemy bodypart
        Rectangle GetTexBBox(Texture2D a_Tex)
        {
            Point UL = new Point(10000, 10000);   // upper left
            Point BR = new Point(-1, -1);           // bottom right

            Color[] data = new Color[a_Tex.Width * a_Tex.Height];
            a_Tex.GetData<Color>(data);

            for (int i = 0; i < a_Tex.Width; ++i)
            {
                for (int j = 0; j < a_Tex.Height; ++j)
                {
                    Color pxCol = data[j * a_Tex.Width + i];
                    if (pxCol.A > 10)
                    {
                        UL.X = Math.Min(UL.X, i);
                        UL.Y = Math.Min(UL.Y, j);
                        BR.X = Math.Max(BR.X, i);
                        BR.Y = Math.Max(BR.Y, j);
                    }
                }
            }

            return new Rectangle(UL.X, UL.Y, BR.X - UL.X, BR.Y - UL.Y);
        }

        public DetailWindowImages(string a_TypeName)
        {
            m_TypeName = a_TypeName;

            string psdName = string.Format("damage\\{0}", a_TypeName);
            MultiTex layers = RogueGame.Instance.Content.Load<MultiTex>(psdName);

            m_PartsToImages = new Dictionary<string, TexAndBBox>();
            for (int i = 0; i < layers.m_Names.Count; ++i)
            {
                TexAndBBox tbb;
                tbb.m_Texture = (Texture2D) layers.m_Layers[i];
                tbb.m_BBox = GetTexBBox(tbb.m_Texture);

                m_PartsToImages[layers.m_Names[i].ToLower()] = tbb;
            }
        }

        // can be "background" or "default" or a bodypart name to look up
        // TODO: exception wrapping? TryGetValue from the dict...
        public Texture2D GetImageFor(String a_Name)
        {
            // if you get an exception here, check your layer names in the psd, and compare them to the bodypart names in your body setup code. 
            // Generally the name is (optional part name if there's more than one) + (part type name), ie "head" or "top doorhinge"
            return m_PartsToImages[a_Name.ToLower()].m_Texture;
        }

        public Rectangle GetPartBBox(String a_Name)
        {
            return m_PartsToImages[a_Name.ToLower()].m_BBox;
        }

        public Point GetTexSize(String a_Name)
        {
            Texture2D tex = m_PartsToImages[a_Name.ToLower()].m_Texture;
            return new Point(tex.Height, tex.Width);
        }
    }
}